'use strict'
const path = require('path')
const pkg = require('./package.json')
// const webpack = require('webpack')
// const dllPath = "./public/vendor/";
// const { library } = require("./dll.config.js");
// const AddAssetHtmlPlugin = require('add-asset-html-webpack-plugin')
const SpeedMeasurePlugin = require('speed-measure-webpack-plugin');
const smp = new SpeedMeasurePlugin({
 outputFormat:'human',
});

const HardSourceWebpackPlugin = require('hard-source-webpack-plugin')

function resolve(dir) {
  return path.join(__dirname, dir)
}

const name = pkg.name || 'iot-business-manage-web' // page title
const port = 8081 // dev port

// All configuration item explanations can be find in https://cli.vuejs.org/config/
module.exports = {
  /**
   * You will need to set publicPath if you plan to deploy your site under a sub path,
   * for example GitHub Pages. If you plan to deploy your site to https://foo.github.io/bar/,
   * then publicPath should be set to "/bar/".
   * In most cases please use '/' !!!
   * Detail: https://cli.vuejs.org/config/#publicpath
   */
  publicPath: '/',
  outputDir: 'dist',
  assetsDir: 'static',
  lintOnSave: process.env.NODE_ENV === 'development' ? 'warning' : false,
  productionSourceMap: false,
  css: {
    extract: true, // 是否使用css分离插件 ExtractTextPlugin
    sourceMap: process.env.NODE_ENV === 'development' ? true : false // 开启 CSS source maps?
  },
  devServer: {
    port: port,
    open: true,
    overlay: {
      warnings: false,
      errors: true
    },
    proxy: {
      // change xxx-api/login => mock/login
      // detail: https://cli.vuejs.org/config/#devserver-proxy
      [process.env.VUE_APP_BASE_API]: {
        target: `http://10.80.9.50:${port}/mock`,
        changeOrigin: true,
        pathRewrite: {
          ['^' + process.env.VUE_APP_BASE_API]: ''
        }
      }
    }
    // after: require('./mock/mock-server.js')
  },
  configureWebpack: smp.wrap({
    // provide the app's title in webpack's name field, so that
    // it can be accessed in index.html to inject the correct title.
    name: name,
    resolve: {
      // modules: [path.resolve(__dirname, 'node_modules')],
      alias: {
        '@': resolve('src'),
        // '_': path.resolve(__dirname, './node_modules/lodash/lodash.min.js'),
        // 'moment': path.resolve(__dirname, './node_modules/moment/moment.js')
      }
    },
    module:{
      // 不解析某些模块
      noParse:/^(vue|vue-router|vuex|lodash|moment|axios|js-cookie|core-js|tooltip.js|qs|screenfull|video.js|videojs-contrib-hls|echarts|wangeditor|vue-json-schema-editor-visual)$/
    },
    plugins: process.env.NODE_ENV === 'production' ? [new HardSourceWebpackPlugin({
      //  cacheDirectory是在高速缓存写入 ，设置缓存在磁盘中存放的路径
      cacheDirectory: './../disk/cache/hard-source/[confighash]',
      recordsPath: './../disk/cache/hard-source/[confighash]/records.json',
      configHash: function(webpackConfig) {
        // node-object-hash on npm can be used to build this.
        return require('node-object-hash')({sort: false}).hash(webpackConfig);
      },
      // 当加载器，插件，其他构建时脚本或其他动态依赖项发生更改时，hard-source需要替换缓存以确保输 
      // 出正确。environmentHash被用来确定这一点。如果散列与先前的构建不同，则将使用新的缓存
      environmentHash: {
        root: process.cwd(),
        directories: [],
        files: ['package-lock.json'],
      },
      info: {
        mode: 'none',
        level: 'debug'
      },
    })] : [],
  }),
  chainWebpack(config) {
    // config
    //   .plugin('webpack-bundle-analyzer')
    //   .use(require('webpack-bundle-analyzer').BundleAnalyzerPlugin)
    
    config.plugin('preload').tap(() => [
      {
        rel: 'preload',
        // to ignore runtime.js
        // https://github.com/vuejs/vue-cli/blob/dev/packages/@vue/cli-service/lib/config/app.js#L171
        fileBlacklist: [/\.map$/, /hot-update\.js$/, /runtime\..*\.js$/],
        include: 'initial'
      }
    ])
    config.plugins.delete('prefetch') // TODO: need test

    config.plugin('extract-css').tap((options) => {
      options[0].filename = 'static/css/[name].[hash:8].css'
      return options
    })

    // set svg-sprite-loader
    config.module
      .rule('svg')
      .exclude.add(resolve('src/icons'))
      .end()
    config.module
      .rule('icons')
      .test(/\.svg$/)
      .include.add(resolve('src/icons'))
      .end()
      .use('svg-sprite-loader')
      .loader('svg-sprite-loader')
      .options({
        symbolId: 'icon-[name]'
      })
      .end()

    // set preserveWhitespace
    config.module
      .rule('vue')
      .use('vue-loader')
      .loader('vue-loader')
      .tap(options => {
        options.compilerOptions.preserveWhitespace = true
        return options
      })
      .end()

    config
      .when(process.env.NODE_ENV === 'development',
        config => config.devtool('cheap-source-map')
      )

    // config
    //   .when(process.env.NODE_ENV !== 'development',
    //     config => {
          config
            .plugin('ScriptExtHtmlWebpackPlugin')
            .after('html')
            .use('script-ext-html-webpack-plugin', [{
            // `runtime` must same as runtimeChunk name. default is `runtime`
              inline: /runtime\..*\.js$/
            }])
            .end()
          config
            .optimization.splitChunks({
              chunks: 'all',
              // minSize: 30000, // 模块的最小体积
              minChunks: 1, // 模块的最小被引用次数
              maxAsyncRequests: 5, // 按需加载的最大并行请求数
              maxInitialRequests: 2, 
              cacheGroups: {
                libs: {
                  name: 'chunk-libs',
                  test: /[\\/]node_modules[\\/]/,
                  priority: 15,
                  chunks: 'initial', // 只打包初始时依赖的第三方
                  reuseExistingChunk: false,
                  enforce: true,
                },
                elementUI: {
                  name: 'chunk-elementUI', // split elementUI into a single package
                  priority: 20, // the weight needs to be larger than libs and app or it will be packaged into libs or app
                  test: /[\\/]node_modules[\\/]_?element-ui(.*)/,
                  chunks: 'all',
                  reuseExistingChunk: false,
                  enforce: true,
                },
                echarts: {
                  name: 'chunk-echarts', // split elementUI into a single package
                  priority: 16, // the weight needs to be larger than libs and app or it will be packaged into libs or app
                  test: /[\\/]node_modules[\\/]_?echarts(.*)/,
                  chunks: 'all',
                  reuseExistingChunk: false,
                  enforce: true,
                },
                videojs: {
                  name: 'chunk-videojs',
                  priority: 17,
                  test: /[\\/]node_modules[\\/]_?video.js(.*)/,
                  chunks: 'all',
                  reuseExistingChunk: false,
                  enforce: true,
                },
                moment: {
                  name: 'chunk-moment',
                  priority: 21,
                  test: /[\\/]node_modules[\\/]_?moment(.*)/,
                  chunks: 'all',
                  reuseExistingChunk: false,
                  enforce: true,
                },
                lodash: {
                  name: 'chunk-lodash',
                  priority: 19,
                  test: /[\\/]node_modules[\\/]_?lodash(.*)/,
                  chunks: 'all',
                  reuseExistingChunk: false,
                  enforce: true,
                },
                jsonschema: {
                  name: 'chunk-jsonschema',
                  priority: 19,
                  test: /[\\/]node_modules[\\/]_?vue-json-schema-editor-visual(.*)/,
                  chunks: 'all',
                  reuseExistingChunk: false,
                  enforce: true,
                },
                wangeditor: {
                  name: 'chunk-wangeditor',
                  priority: 19,
                  test: /[\\/]node_modules[\\/]_?wangeditor(.*)/,
                  chunks: 'all',
                  reuseExistingChunk: false,
                  enforce: true,
                },
                commons: {
                  name: 'chunk-commons',
                  test: resolve('src/components'), // can customize your rules
                  priority: 22,
                  chunks: 'all',
                  reuseExistingChunk: false,
                  enforce: true,
                }
              }
            })
          config.optimization.runtimeChunk('single')
        // }
  //     )
  }
}
